package com.dd.cloud.user.service.goods.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dd.cloud.common.constants.IntegralConstants;
import com.dd.cloud.common.constants.OrderConstants;
import com.dd.cloud.common.constants.SmsConstants;
import com.dd.cloud.common.exception.ZekeException;
import com.dd.cloud.common.interceptor.UserInterceptor;
import com.dd.cloud.common.utils.SerialNumberUtils;
import com.dd.cloud.common.vo.LoginInfo;
import com.dd.cloud.user.config.OrderPrefix;
import com.dd.cloud.user.entity.doctor.DoctorDetail;
import com.dd.cloud.user.entity.doctor.DoctorIntegral;
import com.dd.cloud.user.entity.doctor.DoctorUser;
import com.dd.cloud.user.entity.goods.ConversionGood;
import com.dd.cloud.user.entity.goods.GoodsExchange;
import com.dd.cloud.user.mapper.goods.GoodsExchangeMapper;
import com.dd.cloud.user.mq.MQConfig;
import com.dd.cloud.user.mq.RabbitSend;
import com.dd.cloud.user.req.goods.GoodsExchangeAddFrom;
import com.dd.cloud.user.req.goods.GoodsExchangeReq;
import com.dd.cloud.user.req.goods.GoodsExchangeUpdateFrom;
import com.dd.cloud.user.res.doctor.DoctorIntegralDataRes;
import com.dd.cloud.user.service.doctor.IDoctorDetailService;
import com.dd.cloud.user.service.doctor.IDoctorIntegralService;
import com.dd.cloud.user.service.doctor.IDoctorUserService;
import com.dd.cloud.user.service.goods.IConversionGoodService;
import com.dd.cloud.user.service.goods.IGoodsExchangeService;
import jodd.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 商品积分兑换表 服务实现类
 * </p>
 *
 * @author czg
 * @since 2024-01-17
 */
@Service
public class GoodsExchangeServiceImpl extends ServiceImpl<GoodsExchangeMapper, GoodsExchange> implements IGoodsExchangeService {
    @Autowired
    private IConversionGoodService conversionGoodRecordService;
    @Autowired
    private IDoctorIntegralService doctorIntegralService;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private OrderPrefix orderPrefix;
    @Autowired
    private IDoctorDetailService doctorDetailService;
    @Autowired
    private IDoctorUserService doctorUserService;
    @Autowired
    private RabbitSend rabbitSend;

    @Override
    public Page<GoodsExchange> queryGoodsExchangePage(GoodsExchangeReq req) {
        if (StringUtil.isBlank(req.getTypes())) {
            req.setTypes("1,2,3");
        }
        Page<GoodsExchange> page = req.pagePojo();
        page = this.getBaseMapper().queryGoodsExchangePage(page, req);
        return page;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addGoodsExchange(GoodsExchangeAddFrom from) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        GoodsExchange goodsExchange = new GoodsExchange();
        BeanUtil.copyProperties(from, goodsExchange);
        goodsExchange.setSort(1).setCreateDate(LocalDateTime.now())
                .setUpdateDate(LocalDateTime.now())
                .setOperName(loginInfo.getName()).setStatus(1);
        boolean flag = this.save(goodsExchange);
        if (!flag) {
            throw new ZekeException("保存失败");
        }
        LambdaQueryWrapper<GoodsExchange> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(GoodsExchange::getStatus, 1).orderByAsc(GoodsExchange::getSort);
        List<GoodsExchange> oldList = this.list(queryWrapper);
        if (CollectionUtil.isNotEmpty(oldList)) {
            oldList.forEach(item -> {
                item.setSort(item.getSort() + 1);
            });
            boolean flag1 = this.updateBatchById(oldList);
            if (!flag1) {
                throw new ZekeException("保存失败");
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateGoodsExchange(GoodsExchangeUpdateFrom from) {
        GoodsExchange oldExchange = this.getById(from.getGoodId());
        if (oldExchange == null) {
            throw new ZekeException("记录不存在");
        }
        BeanUtil.copyProperties(from, oldExchange);
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        oldExchange.setUpdateDate(LocalDateTime.now()).setOperName(loginInfo.getName());
        Boolean flag = this.updateById(oldExchange);
        if (!flag) {
            throw new ZekeException("更新失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateGoodsExchangeStatus(Integer goodId, Integer status) {
        if (status != -1) {
            throw new ZekeException("状态传递错误");
        }
        GoodsExchange goodsExchange = this.getById(goodId);
        if (goodsExchange == null) {
            throw new ZekeException("记录不存在");
        }
        goodsExchange.setStatus(-1).setUpdateDate(LocalDateTime.now());
        Boolean flag = this.updateById(goodsExchange);
        if (!flag) {
            throw new ZekeException("删除失败");
        }
        Integer sort = goodsExchange.getSort();
        LambdaQueryWrapper<GoodsExchange> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(GoodsExchange::getStatus, 1).gt(GoodsExchange::getSort, sort).orderByAsc(GoodsExchange::getSort);
        List<GoodsExchange> goodsExchangeList = this.list(wrapper);
        if (CollectionUtil.isNotEmpty(goodsExchangeList)) {
            goodsExchangeList.forEach(item -> {
                item.setSort(item.getSort() - 1);
            });
            boolean flag3 = this.updateBatchById(goodsExchangeList);
            if (!flag3) {
                throw new ZekeException("~删除失败~");
            }
        }
    }


    @Override
    public GoodsExchange queryGoodsExchangeDetail(Integer goodId) {
        GoodsExchange goodsExchange = this.getById(goodId);
        LambdaQueryWrapper<ConversionGood> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ConversionGood::getGoodId, goodId);
        Integer count = conversionGoodRecordService.count(queryWrapper);
        goodsExchange.setSaleCount(count);
        return goodsExchange;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateGoodsExchangeIsShow(Integer goodId, Integer isShow) {
        if (isShow != 0 && isShow != 1) {
            throw new ZekeException("传递状态错误");
        }
        GoodsExchange goodsExchange = this.getById(goodId);
        if (goodsExchange == null) {
            throw new ZekeException("商品不存在");
        }
        goodsExchange.setIsShow(isShow);
        Boolean flag = this.updateById(goodsExchange);
        if (!flag) {
            throw new ZekeException("上下架不存在");
        }
    }

    @Override
    public void moveGoodsExchange(Integer goodId, Integer flag) {
        if (flag != 1 && flag != 2) {
            throw new ZekeException("上下移动标志传递错误");
        }
        GoodsExchange goodsExchange = this.getById(goodId);
        if (goodsExchange == null) {
            throw new ZekeException("商品不存在");
        }
        LambdaQueryWrapper<GoodsExchange> queryWrapper = new LambdaQueryWrapper<>();
        //上移动
        if (flag == 1) {
            queryWrapper.lt(GoodsExchange::getSort, goodsExchange.getSort()).orderByDesc(GoodsExchange::getSort);
            //下移动
        } else if (flag == 2) {
            queryWrapper.gt(GoodsExchange::getSort, goodsExchange.getSort()).orderByAsc(GoodsExchange::getSort);
        }
        queryWrapper.eq(GoodsExchange::getStatus, 1).last("limit 1");
        GoodsExchange oldData = this.getOne(queryWrapper);
        if (oldData == null) {
            throw new ZekeException("暂不支持移动操作");
        }
        Integer preSort = goodsExchange.getSort();
        Integer oldSort = oldData.getSort();
        goodsExchange.setSort(oldSort);
        oldData.setSort(preSort);
        List<GoodsExchange> list = new ArrayList<>();
        list.add(oldData);
        list.add(goodsExchange);
        if (CollectionUtil.isNotEmpty(list)) {
            Boolean flag1 = this.updateBatchById(list);
            if (!flag1) {
                throw new ZekeException("更新失败");
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<Integer, String> exchangeDoctorGoods(Integer goodId, Integer num, String phone) {
        Map<Integer, String> map = new HashMap<>();
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        Integer doctorId = loginInfo.getId();
        DoctorIntegralDataRes res = doctorIntegralService.queryDoctorIntegral();
        if (res == null) {
            map.put(0, "剩余积分不存在");
            return map;
//            throw new ZekeException("剩余积分不存在");
        }
        Integer have = res.getHave();
        if (num > have) {
            map.put(0, "所剩积分不足");
            return map;
//            throw new ZekeException("所剩积分不足");
        }
        //查询商品
        GoodsExchange goodsExchange = this.queryGoodsExchangeDetail(goodId);
        if (goodsExchange == null) {
            map.put(0, "商品不存在");
            return map;
//            throw new ZekeException("商品不存在");
        }
        if (!num.equals(goodsExchange.getIntegral())) {
            map.put(0, "商品积分错误,请确认!");
            return map;
//            throw new ZekeException("商品积分错误,请确认!");
        }
        //查询医生信息
        LambdaQueryWrapper<DoctorDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DoctorDetail::getStatus, 1).eq(DoctorDetail::getDoctorId, doctorId);
        DoctorDetail doctorDetail = doctorDetailService.getOne(queryWrapper);
        if (doctorDetail == null) {
            map.put(0, "医生信息不存在");
            return map;
//            throw new ZekeException("医生信息不存在");
        }
        DoctorUser doctorUser = doctorUserService.getById(doctorId);
        if (doctorUser == null) {
            map.put(0, "医生信息不存在");
            return map;
//            throw new ZekeException("医生信息不存在");
        }
        ConversionGood conversionGood = new ConversionGood();
        String orderNo = SerialNumberUtils.getInstance().generateSerialNumber(redisTemplate, orderPrefix.getExchangeFix());
        conversionGood.setOrderNo(orderNo)
                .setDoctorId(doctorId)
                .setGoodId(goodId)
                .setGoodName(goodsExchange.getName())
                .setExchangeDate(LocalDateTime.now())
                .setCreateDate(LocalDateTime.now())
                .setUpdateName(loginInfo.getName())
                .setUpdateDate(LocalDateTime.now())
                .setType(goodsExchange.getType())
                .setStatus(OrderConstants.ExchangeStatus.WAIT_SEND)
                .setAccount(doctorUser.getMobileNumber())
                .setBuyName(doctorDetail.getName())
                .setPhone(phone)
                .setTypeName(getTypeName(goodsExchange.getType()))
                .setIntegral(num)
                .setImgTextDesc(goodsExchange.getImgTextDesc())
                .setImgUrl(goodsExchange.getImgUrl());
        Boolean flag = conversionGoodRecordService.save(conversionGood);
        if (!flag) {
            throw new ZekeException("保存失败");
        }
        DoctorIntegral doctorIntegral = new DoctorIntegral();
        doctorIntegral.setTitle("商品兑换")
                .setNum(-num)
                .setDoctorId(doctorId)
                .setExchangeNo(orderNo)
                .setType(IntegralConstants.IntegralType.TWENTY)
                .setStatus(3)
                .setCreateDate(LocalDateTime.now())
                .setGiveDate(LocalDateTime.now());
        Boolean flag1 = doctorIntegralService.save(doctorIntegral);
        if (!flag1) {
            throw new ZekeException("保存失败");
        }
        sendExchangeGoodsSms(doctorDetail.getMobileNumber(), doctorDetail.getName(), num);
        map.put(1, "兑换成功");
        return map;
    }

    /**
     * 发送商品兑换短信
     *
     * @param phone
     * @param name
     * @param num
     */
    public void sendExchangeGoodsSms(String phone, String name, Integer num) {
        Map<String, String> msg = new HashMap<>(5);
        msg.put("phone", phone);
        msg.put("name", name);
        msg.put("num", String.valueOf(num));
        msg.put("param_type", SmsConstants.ParamType.JSON);
        msg.put("sms_template", SmsConstants.Template.GOODS_EXCHANGE);
        rabbitSend.sendMessage(MQConfig.SMS_EXCHANGE, MQConfig.SMS_KEY, msg);
    }

    @Override
    public Page<GoodsExchange> queryDoctorGoodsPage(GoodsExchangeReq req) {
        if (StringUtil.isBlank(req.getTypes())) {
            req.setTypes("1");
        }
        req.setIsShow(1);
        Page<GoodsExchange> page = req.pagePojo();
        page = this.getBaseMapper().queryGoodsExchangePage(page, req);
        return page;
    }


    private String getTypeName(Integer type) {
        if (type == 1) {
            return "现金";
        } else if (type == 2) {
            return "话费";
        } else if (type == 3) {
            return "电话卡";
        }
        return "";
    }


}
